﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CNRegex.Web.Base;
using CNRegex.Biz.BizAccess;
using System.Web.Mvc;
using CNRegex.Web.Utility;
using CNRegex.Entity;
using Project.Common;
using System.IO;
using System.Text.RegularExpressions;
using CNRegex.Entity.EntityEx;
using CNRegex.Enum;
using CNRegex.Entity.Others;
using CNRegex.Biz;
using CNRegex.Biz.SPBiz;

namespace CNRegex.Web.Models
{
	#region ModelBlogCreate
	public class ModelBlogCreate:BaseModel
	{
		private BizRegexUserBlogCatalog bizRegexUserBlogCatalog;
		private BizRegexUserBlog bizRegexUserBlog;
		private BizRegexUserBlogContent bizRegexUserBlogContent;
		private BizRegexBook bizRegexBook;
		public Guid BlogID
		{
			get;
			set;
		}
		public RegexUserBlogContent BlogContentEntity
		{
			get;
			set;
		}

		public RegexUserBlog BlogEntity
		{
			get;
			set;
		}

		public ModelBlogCreate(Guid blogID)
		{
			BlogID = blogID;
			//InitialBizObjects();
			//edit blog
			if (!StringUtility.IsEmptyGuid(BlogID))
			{
				BlogEntity = bizRegexUserBlog.GetByID(BlogID);
				BlogContentEntity = bizRegexUserBlogContent.ListBy(x => x.BlogID == BlogEntity.ID, "", EnumOrder.ASC).First();
				BlogCatalog.First(x => x.Value == BlogEntity.CatalogID.ToString()).Selected = true;
			}
		}

		public ModelBlogCreate()
		{

		}

		private IList<SelectListItem> blogCatalog;
		public IList<SelectListItem> BlogCatalog
		{
			get{
				if (blogCatalog != null)
					return blogCatalog;
				SelectList selectList = new SelectList(bizRegexUserBlogCatalog.List(x => x.OrderIndex, Enum.EnumOrder.ASC), "ID", "Name");
				blogCatalog = WebTools.InsertOption(selectList, "", "", false, Enum.EnumLoaction.First);
				return blogCatalog;
			}
		}

		public void Create()
		{
			BlogEntity.CreateDate = DateTime.Now;
			BlogEntity.UserID = FrontContext.CurrentRegexUser.ID;
			BlogEntity.Summery = StringUtility.StripHTML(BlogContentEntity.Content, 200);
			BlogContentEntity.Content = ProcessPicture(BlogContentEntity.Content);
			bizRegexUserBlog.Create(this.BlogEntity, this.BlogContentEntity);
		}

		public void Save()
		{
			BlogEntity.UserID = FrontContext.CurrentRegexUser.ID;
			BlogEntity.Summery = StringUtility.StripHTML(BlogContentEntity.Content, 200);
			BlogContentEntity.Content = ProcessPicture(BlogContentEntity.Content);
			bizRegexUserBlog.Save(this.BlogEntity, this.BlogContentEntity);
		}

		/// <summary>
		/// 处理上传的图片,移动目录,更换内容中的链接地址
		/// </summary>
		/// <param name="content"></param>
		private string ProcessPicture(string content)
		{
			string datePath = string.Format("/Files/Blog/{0}/{1}/{2}/", DateTime.Today.Year.ToString(), DateTime.Today.Month.ToString(), DateTime.Today.Day.ToString());
			string path = HttpContext.Current.Server.MapPath(datePath);
			if (!Directory.Exists(path))
				Directory.CreateDirectory(path);
			Regex regexImgTag = new Regex("<img\\s+src=\"/Files/Temp/([^>])*\\s+/>", RegexOptions.Multiline);
			Regex regexImgName = new Regex("/Files/Temp/([^\"]*)");
			Regex regexTempPath = new Regex("/Files/Temp/");
			MatchCollection collection = regexImgTag.Matches(content);
			if (collection.Count == 0)
				return content;
			for (int i = 0; i < collection.Count; i++)
			{
				Match m = regexImgName.Match(collection[i].Value);
				string imgName = string.Empty;
				if (m.Groups.Count <= 1)
					continue;
				imgName = m.Groups[1].Value;
				string imgTempPath = HttpContext.Current.Server.MapPath(string.Format("/Files/Temp/{0}",imgName));
				if (!File.Exists(imgTempPath))
					continue;
				string imgFormalPath = path + imgName;
				File.Move(imgTempPath, imgFormalPath);
			}
			content = regexTempPath.Replace(content, datePath);
			return content;
			
		}
	}
	#endregion

	#region ModelBlogIndex
	public class ModelBlogIndex : BaseModel
	{
		public int? PageIndex { get; set; }
		public EnumListType? ListType { get; set; }
		public int? DaysBefore { get; set; }
		public Guid? CatalogID { get; set; }
		private BizRegexUserBlog bizRegexUserBlog;
		public ModelBlogIndex()
		{
			ListType = ListType ?? EnumListType.最新;
			DaysBefore = DaysBefore ?? 3;
		}

		private IList<SPListBlogs> contentBlogs;
		public IList<SPListBlogs> ContentBlogs
		{
			get
			{
				ListType = ListType ?? EnumListType.最新;
				switch (ListType)
				{
					case EnumListType.最新:
						return LatestBlogs;
					case EnumListType.热门:
					case EnumListType.推荐:
						return RecommendOrHotBlogs;
					case EnumListType.类别:
						return CatalogBlogs;
					default:
						return null;
				}
			}
		}

		private IList<SPListBlogs> latestBlogs;
		public IList<SPListBlogs> LatestBlogs
		{
			get
			{
				if (latestBlogs != null)
					return latestBlogs;
				latestBlogs = BizFactory.Get<BizSPListBlogs>().Invoke(new SPListBlogsParameter()
				{
					pageSize = ProjectGlobal.PAGE_SIZE,
					pageIndex = PageIndex ?? 0,
					recordType = (int)EnumRecordType.Latest
				});
				exPaginate = new PaginateHelper(ProjectGlobal.PAGE_SIZE, latestBlogs.Count > 0 ? latestBlogs[0].RecordCount.Value : 0, PageIndex ?? 0, string.Format("/Blog/Index/?t={0}&days={1}&", (int)ListType, DaysBefore.Value));
				exPaginate.ParaPageIndex = "p";
				return latestBlogs;
			}
		}

		private IList<SPListBlogs> catalogBlogs;
		public IList<SPListBlogs> CatalogBlogs
		{
			get
			{
				if (catalogBlogs != null)
					return catalogBlogs;
				catalogBlogs = BizFactory.Get<BizSPListBlogs>().Invoke(new SPListBlogsParameter()
				{
					pageSize = ProjectGlobal.PAGE_SIZE,
					pageIndex = PageIndex ?? 0,
					recordType = (int)EnumRecordType.Other,
					catalogID = CatalogID
				});
				exPaginate = new PaginateHelper(ProjectGlobal.PAGE_SIZE, catalogBlogs.Count > 0 ? catalogBlogs[0].RecordCount.Value : 0, PageIndex ?? 0, string.Format("/Blog/Index/?t={0}&c={1}&days={2}&", (int)ListType, CatalogID, DaysBefore.Value));
				exPaginate.ParaPageIndex = "p";
				return catalogBlogs;
			}
		}

		private IList<SPListBlogs> recommendOrHotBlogs;
		public IList<SPListBlogs> RecommendOrHotBlogs
		{
			get
			{
				if (recommendOrHotBlogs != null)
					return recommendOrHotBlogs;
				EnumRecordType recordType = EnumRecordType.Click;
				switch (ListType)
				{
					case EnumListType.推荐:
						recordType = EnumRecordType.Recommend;
						break;
					case EnumListType.热门:
						recordType = EnumRecordType.Click;
						break;
				}

				recommendOrHotBlogs = BizFactory.Get<BizSPListBlogs>().Invoke(new SPListBlogsParameter()
				{
					pageSize = ProjectGlobal.PAGE_SIZE,
					pageIndex = PageIndex ?? 0,
					recordType = (int)recordType,
					 dateBefore=DateTime.Today.AddDays(-DaysBefore.Value)
				});

				exPaginate = new PaginateHelper(ProjectGlobal.PAGE_SIZE, recommendOrHotBlogs.Count > 0 ? recommendOrHotBlogs[0].RecordCount.Value: 0, PageIndex ?? 0, string.Format("/Blog/Index/?t={0}&days={1}&", (int)ListType, DaysBefore.Value));
				exPaginate.ParaPageIndex = "p";
				return recommendOrHotBlogs;
			}
		}


		private PaginateHelper exPaginate;
		public PaginateHelper ExPaginate
		{
			get
			{
				if (exPaginate != null)
					return exPaginate;
				contentBlogs = ContentBlogs;
				return exPaginate;
			}
		}
	}
	#endregion

	#region ModelBlogDetail
	public class ModelBlogDetail : BaseModel
	{
		private const int BLOG_RECOMMEND = 3;
		private const int BLOG_LATEST = 3;
		private BizRegexUserBlog bizRegexUserBlog;
		private BizRegexUserBlogComment bizRegexUserBlogComment;
		private BizRegexUserBlogContent bizRegexUserBlogContent;
		private BizRegexUserBlogRecord bizRegexUserBlogRecord;
		private BizRegexUser bizRegexUser;

		private RegexUser blogAuthor;

		
		public Guid BlogID
		{
			get;
			set;
		}
		public ModelBlogDetail(Guid blogID)
		{
			this.BlogID = blogID;

			//record click information
			Nullable<Guid> nullGuid = null;
			RegexUserBlogRecord record = new RegexUserBlogRecord()
			{
				BlogID = blogID,
				RecordTime = DateTime.Today,
				RecordType = (int)EnumRecordType.Click,
				UserID = FrontContext.CurrentRegexUser == null ? nullGuid : FrontContext.CurrentRegexUser.ID
			};
			bizRegexUserBlogRecord.Save(record);
		}

		public int? PageIndex { get; set; }
		private RegexUserBlog blog;
		public RegexUserBlog Blog
		{
			get
			{
				if (blog != null)
					return blog;
				blog = bizRegexUserBlog.GetByID(BlogID);
				return blog;
			}
		}

		private IList<RegexUserBlog> latestBlogs;
		public IList<RegexUserBlog> LatestBlogs
		{
			get
			{
				if (latestBlogs != null)
					return latestBlogs;
				latestBlogs = bizRegexUserBlog.ListUserLatestBlogs(BlogAuthor.ID, BLOG_LATEST);
				return latestBlogs;
			}
		}

		private IList<RegexUserBlog> recommendBlogs;
		public IList<RegexUserBlog> RecommendBlogs
		{
			get
			{
				if (recommendBlogs != null)
					return recommendBlogs;
				recommendBlogs = bizRegexUserBlog.ListUserRecommendBlogs(BlogAuthor.ID,BLOG_RECOMMEND);
				return recommendBlogs;
			}
		}


		public RegexUser BlogAuthor
		{
			get
			{
				if (blogAuthor != null)
					return blogAuthor;
				blogAuthor = bizRegexUser.GetByID(Blog.UserID);
				return blogAuthor;
			}
		}


		

		private RegexUserBlogContent blogContent;
		public RegexUserBlogContent BlogContent
		{
			get
			{
				if (blogContent != null)
					return blogContent;
				blogContent = bizRegexUserBlogContent.GetByBlogID(BlogID);
				return blogContent;
			}
		}

		private PaginateHelper paginate;
		public PaginateHelper Paginate
		{
			get
			{
				blogComments = BlogComments;
				return paginate;
			}
		}

		private IList<RegexUserBlogCommentEx> blogComments;
		public IList<RegexUserBlogCommentEx> BlogComments
		{
			get
			{
				if (blogComments != null)
					return blogComments;
				int count = 0;
				blogComments = bizRegexUserBlogComment.List(ProjectGlobal.PAGE_SIZE, PageIndex, BlogID, ref count);
				paginate = new PaginateHelper(ProjectGlobal.PAGE_SIZE, count, PageIndex ?? 0, string.Format("/Blog/Detail/{0}/?",BlogID));
				paginate.EmptyTip = "暂无评论,简单讨论一下吧～～";
				return blogComments;
			}
		}




	}
	#endregion

	#region ModelBlogSearch

	public class ModelBlogSearch : BaseModel
	{

		private BizRegexUserBlog bizRegexUserBlog;
		public ModelBlogSearch()
		{
			bizRegexUserBlog = BizFactory.Get<BizRegexUserBlog>();
		}

		public int? PageIndex { get; set; }

		private SearchBlogEntity searchBlog;
		public SearchBlogEntity SearchBlog
		{
			get
			{
				if (searchBlog != null)
				{
					if (searchBlog.OrderClick == null && searchBlog.OrderRecommend == null&&searchBlog.OrderCreateDate==null)
						searchBlog.OrderCreateDate = EnumOrder.DESC;
					return searchBlog;
				}
				return null;
			}
			set
			{
				searchBlog = value;
			}
		}

		private IList<SelectListItem> blogCatalog;
		public IList<SelectListItem> BlogCatalog
		{
			get
			{
				if (blogCatalog != null)
					return blogCatalog;
				SelectList selectList = new SelectList(RegexUserBlogCataloies, "ID", "Name");
				blogCatalog = WebTools.InsertOption(selectList, "", "", false, Enum.EnumLoaction.First);
				return blogCatalog;
			}
		}

		private IList<SPSearchBlogs> blogs;
		public IList<SPSearchBlogs> Blogs
		{
			get
			{
				if (blogs != null)
					return blogs;

				blogs = BizFactory.Get<BizSPSearchBlogs>().Invoke(new SPSearchBlogsParameter
				{
					pageSize = ProjectGlobal.PAGE_SIZE,
					pageIndex = PageIndex ?? 0,
					catalogID = searchBlog.UserBlogCatalogID,
					keyWords = searchBlog.Keywords,
					orderClick = WebTools.ConvertNullableEnumToInt<EnumOrder?, EnumOrder>(searchBlog.OrderClick),
					orderCreateDate = WebTools.ConvertNullableEnumToInt<EnumOrder?, EnumOrder>(searchBlog.OrderCreateDate),
					orderRecommend = WebTools.ConvertNullableEnumToInt<EnumOrder?, EnumOrder>(searchBlog.OrderRecommend)
				});


				string orderKey = "";
				string direction = "";
				if (SearchBlog.OrderClick != null)
				{
					orderKey = "click";
					direction = ((int)SearchBlog.OrderClick).ToString();
				}
				else if (SearchBlog.OrderRecommend != null)
				{
					orderKey = "recommend";
					direction = ((int)SearchBlog.OrderRecommend).ToString();
				}
				else
				{
					orderKey = "date";
					direction = ((int)SearchBlog.OrderCreateDate).ToString();
				}

				exPaginate = new PaginateHelper(ProjectGlobal.PAGE_SIZE, blogs.Count > 0 ? blogs[0].RecordCount.Value : 0, PageIndex ?? 0, string.Format("/Blog/Search/?c={0}&k={1}&ok={2}&d={3}&", SearchBlog.UserBlogCatalogID, HttpUtility.UrlEncode(SearchBlog.Keywords),orderKey,direction));
				exPaginate.ParaPageIndex = "p";
				return blogs;
			}
		}

		private PaginateHelper exPaginate;
		public PaginateHelper ExPaginate
		{
			get
			{
				if (exPaginate != null)
					return exPaginate;
				blogs = Blogs;
				return exPaginate;
			}
		}

	}

	#endregion
}